﻿using Common;
using Http.HeartBeat;
using Log4_Net;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Net.Http;
using System.Threading.Tasks;

namespace Http
{
    public static class HttpClient2
    {
        public static string API_ADDRESS = null;
        public static IServiceCollection AddHttpClients([NotNull] this IServiceCollection services)
        {
            IConfiguration configuration = services.GetConfiguration();
            API_ADDRESS = configuration["API_ADDRESS"] ?? "http://localhost";
            services.AddSingleton(typeof(IHttpClientHelper), typeof(HttpClientHelper));

            var HeartBeat = configuration["HeartBeat:Enabled"]==null ? false : configuration["HeartBeat:Enabled"].ToBool();
            if (HeartBeat) {
                services.AddHostedService<HeartBeatService>();
            }
            return services;
        }
    }
    public class HttpClientHelper : IHttpClientHelper
    {
        private readonly object LockObj = new object();
        private static HttpClient client = null;
        private static ILogger _logger = null;
        public static string API_ADDRESS = null;
        
        public HttpClientHelper(ILogHelper _ILogHelper, string[] Headers = null)
        {
            GetInstance(Headers);
            API_ADDRESS = HttpClient2.API_ADDRESS;
            _logger = _ILogHelper.GetLogger();
        }
        public void Startup()
        {
            //帮HttpClient热身
            client.SendAsync(new HttpRequestMessage
            {
                Method = new HttpMethod("HEAD"),
                RequestUri = new Uri(API_ADDRESS + "/")
            }).Result.EnsureSuccessStatusCode();
        }
        public HttpClient GetInstance(string[] Headers = null)
        { 
            if (client == null)
            {
                lock (LockObj)
                {
                    if (client == null)
                    {
                        client = new HttpClient();
                    }
                }
            }
            if (Headers != null && client.DefaultRequestHeaders.Authorization == null)
                client.DefaultRequestHeaders.Add(Headers[0], Headers[1]);
            else if (Headers != null && client.DefaultRequestHeaders.Authorization != null)
            {
                client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Headers[1].Replace("Bearer ", ""));
            }
            return client;
        }

        public string GetHost() {
            return API_ADDRESS;
        }
        public async Task<string> PostAsync(string url, string strJson)//post异步请求方法
        {
            try
            {
                HttpContent content = new StringContent(strJson);

                content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
                //由HttpClient发出异步Post请求
                HttpResponseMessage res = await client.PostAsync(url, content);
                if (res.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    string str = res.Content.ReadAsStringAsync().Result;
                    return str;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.Message + ex.StackTrace);
                return null;
            }
        }

        public string Post(string url, string strJson, string MediaType = "application/json")//post同步请求方法
        {
            try
            {
                HttpContent content = new StringContent(strJson);

                content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(MediaType);
                //client.DefaultRequestHeaders.Connection.Add("keep-alive");
                //由HttpClient发出Post请求
                Task<HttpResponseMessage> res = client.PostAsync(url, content);
                if (res.Result.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    string str = res.Result.Content.ReadAsStringAsync().Result;
                    return str;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.Message + ex.StackTrace);
                return null;
            }
        }

        public string Get(string url)
        {
            try
            {
                var responseString = client.GetStringAsync(url);
                return responseString.Result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.Message + ex.StackTrace);
                return null;
            }
        }

    }
}
